<?php
namespace app\api\service;

use app\api\model\Order as OrderModel;
use app\api\service\Order as OrderService;
use app\lib\exception\OrderException;
use app\lib\exception\TokenException;
use app\lib\enum\OrderStatusEnum;
use think\Exception;
use think\Loader;
use think\Log;

// (子文件夹.类名,extend文件夹所在的目录,后缀)
Loader::import('Wxpay.WxPay',EXTEND_PATH,'.Api.php');//建议手动导入
class Pay {
	private $orderID;
	private $orderNO;

	public function __construct($orderID){
		if(!$orderID){
			throw new Exception('订单号不允许为空');
		}
		$this->orderID = $orderID;
	}

	public function pay(){
		// 订单号可能根本不存在
		// 订单号确实存在，但是，订单号和当前用户不匹配
		// 订单有可能已经被支付过
		// 进行库存量检测
		$this->checkOrderValid();
		$orderService = new OrderService();
		$status = $orderService->checkOrderStock($this->orderID);
		if(!$status['pass']){
			return $status;
		}
		return $this->makeWxPreOrder($status['orderPrice']);
	}

	private function makeWxPreOrder($totalPrice){
		// openid
		$openid = Token::getCurrentTokenVar('openid');
		if(!$openid){
			throw new TokenException();
		}
		$wxOrderData = new \WxPayUnifiedOrder();
		$wxOrderData->SetOut_trade_no($this->orderNO);
		$wxOrderData->SetTrade_type('JSAPI');
		$wxOrderData->SetTotal_fee($totalPrice * 100);
		$wxOrderData->SetBody('零食商贩');
		$wxOrderData->SetOpenid($openid);
		// $wxOrderData->APPID = config('wx.app_id');
		// $wxOrderData->APPSECRET = config('wx.app_secret');
		$wxOrderData->SetNotify_url(config('secure.pay_back_url'));

        return $this->getPaySignature($wxOrderData);
	}

	private function getPaySignature($wxOrderData){
		$wxOrder = \WxPayApi::unifiedOrder($wxOrderData);
		 // 失败时不会返回result_code
        if($wxOrder['return_code'] != 'SUCCESS' || $wxOrder['result_code'] !='SUCCESS'){
            Log::record($wxOrder,'error');
            Log::record('获取预支付订单失败','error');
			// throw new Exception('获取预支付订单失败');
        }
        $this->recordPreOrder($wxOrder);
        $signature = $this->sign($wxOrder);
        return $signature;

	}

	private function sign($wxOrder){
		$jsApiPayData = new \WxPayJsApiPay();
		$jsApiPayData->SetAppid(config('wx.app_id'));
		$jsApiPayData->SetTimeStamp((string)time());

		$rand = md5(time() . mt_rand(0,1000));
		$jsApiPayData->SetNonceStr($rand);

		$jsApiPayData->SetPackage('prepay_id=' . $wxOrder['prepay_id']);
		$jsApiPayData->SetSignType('md5');

		$sign = $jsApiPayData->MakeSign();

		$rawValues = $jsApiPayData->getValues();
		$rawValues['paySign'] = $sign;

		unset($rawValues['appID']);

		return $rawValues;
	}

	private function recordPreOrder($wxOrder){
		OrderModel::where('id','=',$this->orderID)->update(['prepay_id'=>$wxOrder['prepay_id']]);
	}

	private function checkOrderValid(){
		$order = OrderModel::where('id','=',$this->orderID)->find();
		if(!$order){
			throw new OrderException();
		}
		if(!Token::isValidOperate($order->user_id)){
			throw new TokenException([
					'msg' => '订单与用户不匹配',
					'errorCode' => 10003
				]);
		}
		if($order->status != OrderStatusEnum::UNPAID){
			throw new OrderException([
					'msg' => '订单已经支付过啦',
					'errorCode' => 80003,
					'code' => 400
				]);
		}
		$this->orderNO = $order->order_no;
		return true;
	}

}
?>